﻿using NHibernate.Engine;
using NHibernate.Properties;
using System.Collections;
using System.Reflection;

namespace Inovout.Models
{
    public class DictionaryAccessor : IPropertyAccessor
    {
        public IGetter GetGetter(System.Type theClass, string propertyName)
        {
            return new DictionaryGetter(theClass, propertyName);
        }

        public ISetter GetSetter(System.Type theClass, string propertyName)
        {
            return new DictionarySetter(propertyName);
        }

        public bool CanAccessThroughReflectionOptimizer
        {
            get { return false; }
        }

        public class DictionaryGetter : IGetter
        {
            private System.Type theClass;
            private string propertyName;

            public DictionaryGetter(System.Type theClass, string propertyName)
            {
                this.theClass = theClass;
                this.propertyName = propertyName;
            }

            public object Get(object target)
            {
                IDictionary container = (IDictionary)target;
                return container[propertyName];
            }

            public System.Type ReturnType
            {
                get { return theClass; }
            }

            public string PropertyName
            {
                get { return propertyName; }
            }

            public MethodInfo Method
            {
                get { return null; }
            }

            public object GetForInsert(object owner, IDictionary mergeMap, ISessionImplementor session)
            {
                return Get(owner);
            }

            // Optional operation (return null)
        }

        public class DictionarySetter : ISetter
        {
            private string propertyName;

            public DictionarySetter(string propertyName)
            {
                this.propertyName = propertyName;
            }

            public void Set(object target, object value)
            {
                IDictionary container = (IDictionary)target;
                container[propertyName] = value;
            }

            public string PropertyName
            {
                get { return propertyName; }
            }

            public MethodInfo Method
            {
                get { return null; }
            } // Optional operation
        }
    }

}
